# import socket
# import threading

# def recv_data(conn):
#     """持续接收客户端数据并以16进制显示"""
#     while True:
#         data = conn.recv(1024)
#         if not data:
#             print("客户端已断开连接。")
#             break
#         hex_str = data.hex().upper()
#         print(f"\n收到数据(16进制): {hex_str}")

# def send_data(conn):
#     """等待用户输入16进制字符串并发送到客户端"""
#     while True:
#         user_input = input("请输入要发送的16进制字符串（回车跳过）：").strip()
#         if user_input:
#             try:
#                 data = bytes.fromhex(user_input)
#                 conn.sendall(data)
#                 print(f"已发送数据(16进制): {user_input.upper()}")
#             except ValueError:
#                 print("输入的不是有效的16进制字符串！")

# def main():
#     HOST = '0.0.0.0'
#     PORT = 14121

#     with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
#         s.bind((HOST, PORT))
#         s.listen()
#         print(f"TCP服务端已启动，监听端口 {PORT} ...")
#         conn, addr = s.accept()
#         print(f"已连接客户端: {addr}")

#         # 启动接收线程
#         recv_thread = threading.Thread(target=recv_data, args=(conn,), daemon=True)
#         recv_thread.start()

#         # 主线程负责发送
#         send_data(conn)

def crc16_xmodem(data: bytes) -> int:
    """
    计算CRC-16/XMODEM校验码
    多项式: 0x1021
    初始值: 0x0000
    输入/输出不反转，无异或
    :param data: 需要校验的数据（bytes类型）
    :return: CRC16校验码（int类型，高字节在前，低字节在后）
    """
    crc = 0x0000
    for byte in data:
        crc ^= (byte << 8)
        for _ in range(8):
            if crc & 0x8000:
                crc = (crc << 1) ^ 0x1021
            else:
                crc <<= 1
            crc &= 0xFFFF  # 保持16位
    return crc


# 数据协议构造函数
def construct_protocol(device_id, data):
    # 4个字节的设备ID 为AB441AB5
    """构造数据协议"""
    # 构造一个16进制数组，数据头是0x68 数据尾是0x16
    protocol = bytearray()
    protocol.append(0x68)  # 数据头
    # 添加数据长度 2个字节 不包含头尾
    length = len(data) + 4  # 包含设备ID的4个字节
    if length > 512:
        raise ValueError("数据长度超过512字节限制")
    protocol.append(length & 0xFF)  # 高字节和低字节
    protocol.append((length >> 8) & 0xFF)

    # 添加数据类型和控制字 总共2个字节第一个字节为0x80 第二个字节为0x23
    protocol.append(0x80)  # 数据类型
    protocol.append(0x23)  # 控制字
    # 添加设备ID
    protocol.extend(device_id)  # 设备ID 4个字节
    protocol.extend(data)  # 添加数据
    # CRC校验 crc modbus 不含数据头和尾
    crc = crc16_xmodem(protocol[1:])  # 不包含头和尾
    protocol.append(crc & 0xFF)  # 低字节
    protocol.append((crc >> 8) & 0xFF)  # 高字节

    protocol.append(0x16)  # 数据尾
    # 打印出来
    # print(f"构造的协议数据: {protocol.hex().upper()}")
    # print(f"{protocol.hex().upper()}")
    return f"{protocol.hex().upper()}"


if __name__ == "__main__":
    device_id1 = b'\x8F\x91\xCD\x2F'  # 设备Id倒序
    str1 = "+++"
    str2 = "AT+READBINDMAC?\r\n"
    str3 = "AT+WRITEBINDMAC=00000000000F,F4ACF34B241C,600D9434E51C,27432873E41C,000000000000,000000000000,000000000000,000000000000\r\n"  # 示例字符串
    str4 = "AT+RESET\r\n"

    print(construct_protocol(device_id1, bytes(str1, 'utf-8')))
    print(construct_protocol(device_id1, bytes(str2, 'utf-8')))
    print(construct_protocol(device_id1, bytes(str3, 'utf-8')))
    print(construct_protocol(device_id1, bytes(str4, 'utf-8')))
    # # 转换成16进制
    # str1 = bytes(str3, 'utf-8')  # 将字符串转换为字节
    # construct_protocol(str1)  # 测试构造协议函数
